package design.pattern.singleton;

/**
 * @author futao
 * Created on 2017/11/27 - 9:00.
 */

/**
 * 单例模式  singleton
 */
public class SingleTon {
    /**
     * 1.私有构造方法
     */
    private SingleTon() {
    }

    /**
     * 2.用来保存单例对象
     * volatile，最简单的理解方式是volatile修饰符阻止了变量访问前后JVM编译器的指令重排，保证了指令执行顺序。
     */
    private volatile static SingleTon instance = null;

    /**
     * 3.获取对象实例
     * 如果单例初始值是null，还未构建，则构建单例对象并返回。这个写法属于单例模式当中的懒汉模式。
     * 如果单例对象一开始就被new Singleton()主动构建，则不再需要判空操作，这种写法属于饿汉模式。
     *
     * @return SingleTon
     * @version 1.0
     */
//    public static SingleTon getInstanceV1() {
//        if (instance == null) {
//            instance = new SingleTon();
//        }
//        return instance;
//    }

    /**
     * 获取对象实例
     *
     * @return SingleTon
     * @version 2.0
     */
    public static SingleTon getInstanceV2() {
        if (instance == null) {
            /*同步锁，防止多线程同时访问的时候创建出两个不同的实例，其他试图访问该对象的线程将被阻塞*/
            synchronized (SingleTon.class) {
                /*双重检测机制*/
                if (instance == null) {
                    instance = new SingleTon();
                }
            }
        }
        return instance;
    }

    public synchronized static SingleTon getInstance() {
        if (instance == null) {
            instance = new SingleTon();
        }
        return instance;
    }


    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        SingleTon singleTon = (SingleTon) o;

        return name != null ? name.equals(singleTon.name) : singleTon.name == null;
    }

    @Override
    public int hashCode() {
        return name != null ? name.hashCode() : 0;
    }
}

